package com.xjgz.aio.socket.pro.extension.multiplex;

import com.xjgz.aio.socket.pro.extension.plugins.Plugin;

import java.nio.channels.AsynchronousChannelGroup;
import java.util.ArrayList;
import java.util.List;

/**
 * 多用复用客户端配置选项类
 *
 * <p>
 * 该类用于配置多路复用客户端的各种参数，包括连接参数、缓冲区配置、
 * 超时设置、SSL配置等。通过该类可以灵活地控制客户端的行为。
 * </p>
 *
 * <p>主要配置项包括</p>
 * <ul>
 *     <li>网络连接参数：主机地址、端口、连接超时等</li>
 *     <li>缓冲区配置：读写缓冲区大小和数量</li>
 *     <li>安全配置：SSL加密开关</li>
 *     <li>性能配置：最大连接数、空闲超时时间</li>
 *     <li>扩展配置：插件列表</li>
 * </ul>
 *
 * @param <T>
 */
public class MultiplexOptions<T> {

    /**
     * 绑定线程池资源组
     * <p>
     * 用于指定客户端使用的异步通道组，如果为null则使用默认的通道组。
     * 通过共享AsynchronousChannelGroup可以在多个客户端之间共享线程资源，
     * 提高资源利用率
     * </p>
     */
    private AsynchronousChannelGroup group;

    /**
     * 连接超时时间
     */
    private int connectTimeout;

    /**
     * 空闲超时时间
     */
    private int idleTimeout = 60000;

    /**
     * 读缓冲区大小
     */
    private int readBufferSize = 1024;

    /**
     * 写缓冲区块大小
     */
    private int writeChunkSize = 1024;

    // 写缓冲区块个数
    private int writeChunkCount;

    /**
     * 目标服务器主机地址
     */
    private String host;

    /**
     * 目标服务器端口
     */
    private int port;

    /**
     * SSL加密开关
     */
    private boolean ssl;

    /**
     * 最大连接数限制
     * <p>
     * 控制客户端可以同时维持的最大连接数量，防止资源耗尽。
     * 合理设置该值可以在系统性能和资源消耗之间取得平衡。
     * </p>
     */
    private int maxConnections = 128;

    private final List<Plugin<T>> plugins = new ArrayList<>();

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public boolean isSsl() {
        return ssl;
    }

    public void setSsl(boolean ssl) {
        this.ssl = ssl;
    }

    public List<Plugin<T>> getPlugins() {
        return plugins;
    }

    public MultiplexOptions<T> addPlugin(Plugin<T> plugin) {
        plugins.add(plugin);
        return this;
    }

    public MultiplexOptions<T> group(AsynchronousChannelGroup group) {
        this.group = group;
        return this;
    }

    public AsynchronousChannelGroup group() {
        return group;
    }

    public int getConnectTimeout() {
        return connectTimeout;
    }

    public MultiplexOptions<T> connectTimeout(int connectTimeout) {
        this.connectTimeout = connectTimeout;
        return this;
    }

    int idleTimeout() {
        return idleTimeout;
    }

    public MultiplexOptions<T> idleTimeout(int idleTimeout) {
        this.idleTimeout = idleTimeout;
        return this;
    }

    int getMaxConnections() {
        return maxConnections;
    }

    public MultiplexOptions<T> maxConnections(int maxConnections) {
        this.maxConnections = maxConnections;
        return this;
    }

    public void setWriteBuffer(int chunkSize, int chunkCount) {
        this.writeChunkSize = chunkSize;
        this.writeChunkCount = chunkCount;
    }

    int getReadBufferSize() {
        return readBufferSize;
    }

    public void setReadBuffer(int readBufferSize) {
        this.readBufferSize = readBufferSize;
    }

    int getIdleTimeout() {
        return idleTimeout;
    }

    int getWriteChunkSize() {
        return writeChunkSize;
    }

    int getWriteChunkCount() {
        return writeChunkCount;
    }
}
